home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / threads / ThreadsMain.c < prev    next >
C/C++ Source or Header  |  1991-05-29  |  15KB  |  540 lines

  1. /* begincopyright
  2.   Copyright (c) 1988 Xerox Corporation. All rights reserved.
  3.   Use and copying of this software and preparation of derivative works based
  4.   upon this software are permitted. Any distribution of this software or
  5.   derivative works must comply with all applicable United States export
  6.   control laws. This software is made available AS IS, and Xerox Corporation
  7.   makes no warranty about the software, its performance or its conformity to
  8.   any specification. Any person obtaining a copy of this software is requested
  9.   to send their name and post office or electronic mail address to:
  10.     PCR Coordinator
  11.     Xerox PARC
  12.     3333 Coyote Hill Rd.
  13.     Palo Alto, CA 94304
  14.   endcopyright */
  15. /*
  16.  * ThreadsMain.c
  17.  *
  18.  * Demers, November 30, 1990 11:08:16 am PST
  19.  * Boehm, May 29, 1991 5:02:08 pm PDT
  20.  *
  21.  * Startup code for Xerox Runtime threads package.
  22.  */
  23.  
  24. #include "xr/BasicTypes.h"
  25. #include "xr/Threads.h"
  26. #include "xr/ThreadsBackdoor.h"
  27. #include "xr/ThreadsMsg.h"
  28. #include "xr/ThreadsMsgPrivate.h"
  29. #include "xr/CommandLoop.h"
  30.  
  31. #include <sys/types.h>
  32. #include <sys/file.h>
  33. #include <unistd.h>
  34. #include <strings.h>
  35.  
  36. /*
  37.  * Startup configuration and arg processing ...
  38.  */
  39.  
  40. extern char XR_threadsVersion[];
  41.  
  42. unsigned XR_maxVPs = 1;
  43. unsigned XR_maxSlaveIOPs = 0;
  44. unsigned XR_maxStdIOPs = 1;
  45. unsigned XR_maxStrIOPs = 1;
  46. unsigned XR_maxIOPs = 0;
  47. unsigned XR_maxThreads = 40;
  48. unsigned XR_maxSysMem = XR_MAX_SYS_MEM;
  49. int XR_maxThreadStackGroups = 0;
  50. struct XR_ThreadStackGroupRep
  51.     XR_threadStackGroups[XR_MAX_THREAD_STACK_GROUPS];
  52. int XR_threadStackBytes = XR_THREAD_STACK_BYTES;
  53.  
  54.  
  55. int XR_argc;
  56. char **XR_argv;
  57.  
  58. static void XR_Usage();
  59.  
  60.  
  61.  
  62. static bool XR_helloWorldPrinted = FALSE;
  63.  
  64. static void
  65. XR_PrintHelloWorld(level)
  66.     int level;
  67. {
  68.     if( XR_helloWorldPrinted ) return;
  69.     if( !XR_VERBOSE(level) ) return;
  70.     XR_helloWorldPrinted = TRUE;
  71.     XR_VMsg "\n\nXerox Portable Common Runtime (PCR).\n");
  72.     XR_VMsg "Version %s\n", &(XR_threadsVersion[0]));
  73.     XR_VMsg "  %s (pid %d)\n\n", XR_argv[0], getpid() );
  74. }
  75.  
  76.  
  77. void
  78. XR_Configure ()
  79. {
  80.     int i;
  81.     int nofile;
  82.     int assignedIOPs = 0;
  83.     char *tmpStr;
  84.  
  85.  
  86.     nofile = getdtablesize();
  87.     for( i = 0; i < nofile; i++ ) {
  88.         if( (i != XR_stdInFD) && (i != XR_stdOutFD) )
  89.             (void) close(i);
  90.     }
  91.  
  92.     XR_NormalVMsg "  -vp %d", XR_maxVPs);
  93.  
  94.     XR_NormalVMsg "  -slaveiop %d", XR_maxSlaveIOPs);
  95.     assignedIOPs += XR_maxSlaveIOPs;
  96.  
  97.     XR_NormalVMsg "  -striop %d", XR_maxStrIOPs);
  98.     assignedIOPs += XR_maxStrIOPs;
  99.  
  100.     XR_NormalVMsg "  -stdiop %d", XR_maxStdIOPs);
  101.     assignedIOPs += XR_maxStdIOPs;
  102.  
  103.     XR_maxIOPs = assignedIOPs;
  104.     if( XR_maxIOPs > XR_MAX_IOPS ) XR_Usage("too many IOPs total");
  105.  
  106.     if( XR_maxThreads <= XR_maxVPs ) XR_Usage("-thread: too small");
  107.     if( XR_maxThreadStackGroups == 0 ) {
  108.         XR_threadStackGroups[0].tsg_numThreads = XR_maxThreads;
  109.         XR_threadStackGroups[0].tsg_stackBytes = XR_threadStackBytes;
  110.         XR_maxThreadStackGroups = 1;
  111.     }
  112.     XR_NormalVMsg "\n\t-thread ");
  113.     for( i = 0; i < XR_maxThreadStackGroups; i++ ) {
  114.         XR_NormalVMsg "%d %d",
  115.                 XR_threadStackGroups[i].tsg_numThreads,
  116.                 XR_threadStackGroups[i].tsg_stackBytes );
  117.     }
  118.  
  119.     XR_NormalVMsg "  -stack %d", XR_threadStackBytes);
  120.     if( XR_threadStackBytes > 
  121.             XR_threadStackGroups[XR_maxThreadStackGroups-1].tsg_stackBytes )
  122.         XR_Usage("-stack: too big");
  123.  
  124.     XR_NormalVMsg "  -mem %d", XR_maxSysMem);
  125.  
  126.     if( (tmpStr = XR_GetShmArg()) == NIL ) tmpStr = "";
  127.     XR_NormalVMsg "  -shmtype %s %s", XR_GetShmType(), tmpStr);
  128.  
  129.     XR_NormalVMsg "\n\t-tmpdir %s", XR_GetTmpDirectory());
  130.  
  131.     if( (tmpStr = XR_GetDBXScriptName()) != NIL ) {
  132.         XR_NormalVMsg "\n\t-dbxscript %s", tmpStr);
  133.     } else {
  134.         XR_NormalVMsg "\n\t-nodbxscript");
  135.     }
  136.  
  137.     if( (tmpStr = XR_GetPCRFileName()) != NIL ) {
  138.         XR_NormalVMsg "\n\t-dyload %s", tmpStr);
  139.     } else {
  140.         XR_NormalVMsg "\n\t-nodyload");
  141.     }
  142.  
  143.     XR_NormalVMsg "\n\n");
  144. }
  145.  
  146.  
  147. static void
  148. XR_ParseSwitches(argc, argv, message, usage)
  149.     int argc;
  150.     char ** argv;
  151.     void (*message)(/* char *msg, ... */);
  152.     void (*usage)(/* char *msg */);
  153. {
  154.     int i;
  155. #   define ECHO (*message)(
  156. #   define USAGE (*usage)(
  157. #   define AEQ(s) (strcmpcase(a,(s)) == 0)
  158.  
  159.     i = 0;
  160.     while( i < argc ) {
  161.         char *a = argv[i++];
  162.         int intarg;
  163.         unsigned cardarg;
  164.         char *strarg;
  165.         char *strarg2;
  166.         char *errmsg;
  167.         int defaultVerbosity = (-1);
  168.  
  169.  
  170.         if( AEQ("-dbx") || AEQ("-dbxscript") ) {
  171.             if( (i < argc) && (argv[i][0] != '-') ) {
  172.                 strarg = argv[i++];
  173.                 ECHO "  %s %s\n", a, strarg);
  174.             } else {
  175.                 strarg = XR_DEFAULT_DBX_SCRIPT_NAME;
  176.                 ECHO "  %s\n", a);
  177.             }
  178.             if( XR_SetDBXScriptName(strarg) != 0 )
  179.                 USAGE "%s: bad name", a);
  180.             continue;
  181.         } else if( AEQ("-nodbx") || AEQ("-nodbxscript") ) {
  182.             (void) XR_SetDBXScriptName(NIL);
  183.             continue;
  184.         }
  185.  
  186.         if( AEQ("-dyload") ) {
  187.             if( (i < argc) && (argv[i][0] != '-') ) {
  188.                 strarg = argv[i++];
  189.                 ECHO "  %s %s\n", a, strarg);
  190.             } else {
  191.                 strarg = XR_argv[0];
  192.                 ECHO "  %s\n", a);
  193.             }
  194.             if( XR_SetPCRFileName(strarg) != 0 )
  195.                 USAGE "%s: bad symbol file name", a);
  196.             continue;
  197.         } else if( AEQ("-nodyload") ) {
  198.             (void) XR_SetPCRFileName(NIL);
  199.             continue;
  200.         }
  201.  
  202.         if( AEQ("-mem") ) {
  203.         if( i >= argc ) XR_Usage("%s: missing arg", a);
  204.         cardarg = (unsigned) atoi(argv[i++]);
  205.         ECHO "  %s %d\n", a, cardarg);
  206.         if( cardarg < XR_MAX_SYS_MEM ) cardarg = XR_MAX_SYS_MEM;
  207.         XR_maxSysMem = cardarg;
  208.         continue;
  209.     }
  210.  
  211.     if( AEQ("-v") || AEQ("-verbose") ) {
  212.         defaultVerbosity = XR_VERBOSITY_VERBOSE;
  213.     } else if( AEQ("-quiet") ) {
  214.         defaultVerbosity = XR_VERBOSITY_QUIET;
  215.     } else if( AEQ("-msgs") ) {
  216.         defaultVerbosity = XR_VERBOSITY_NORMAL;
  217.     }
  218.     if( defaultVerbosity >= 0 ) {
  219.         /* funny structure so "-quiet" doesn't echo */
  220.         if( (i < argc) && ((argv[i])[0] != '-') ) {
  221.             if( strcmpcase(argv[i], "verbose") == 0 ) {
  222.                 intarg = XR_VERBOSITY_VERBOSE;
  223.             } else if( strcmpcase(argv[i], "quiet") == 0 ) {
  224.                 intarg = XR_VERBOSITY_QUIET;
  225.             } else if( strcmpcase(argv[i], "normal") == 0 ) {
  226.                 intarg = XR_VERBOSITY_NORMAL;
  227.             } else {
  228.                 intarg = atoi(argv[i]);
  229.             }
  230.             if( intarg < 0 ) USAGE "%s: bad level\n", a);
  231.             XR_verbosity = intarg;
  232.             ECHO "  %s %s\n", a, argv[i]);
  233.             i += 1;
  234.         } else {
  235.             XR_verbosity = defaultVerbosity;
  236.             ECHO "  %s\n", a);
  237.         }
  238.         continue;
  239.     }
  240.  
  241.     if( AEQ("-shmtype") ) {
  242.         if (i >= argc) USAGE "%s: missing arg", a);
  243.         strarg = argv[i++];
  244.         strarg2 = NIL;
  245.         if( (i < argc) && (argv[i][0] != '-') ) strarg2 = argv[i++];
  246.         ECHO "  %s %s %s\n", a, strarg, (strarg2 ? strarg2 : "") );
  247.         if( (errmsg = XR_SetShmType(strarg)) != NIL ) {
  248.             USAGE "bad shmtype (%s)", errmsg);
  249.         }
  250.         if( strarg2 != NIL ) {
  251.                 if( (errmsg = XR_SetShmArg(strarg2)) != NIL ) {
  252.                 USAGE "bad shm arg (%s)", errmsg);
  253.             }
  254.         }
  255.         continue;
  256.     }
  257.  
  258.     if( AEQ("-slave") || AEQ("-slaveiop") ) {
  259.         if( i >= argc ) XR_Usage("%s: missing arg", a);
  260.         cardarg = (unsigned) atoi(argv[i++]);
  261.         ECHO "  %s %d\n", a, cardarg);
  262.         if( cardarg > XR_MAX_SLAVEIOPS ) USAGE "%s: too big", a);
  263.         XR_maxSlaveIOPs = cardarg;
  264.         continue;
  265.     }
  266.  
  267.     if( AEQ("-stack") || AEQ("-stackbytes") ) {
  268.         if( i >= argc ) XR_Usage("%s: missing arg", a);
  269.         cardarg = (unsigned) atoi(argv[i++]);
  270.         ECHO "  %s %d\n", a, cardarg);
  271.         if( cardarg < XR_MIN_THREAD_STACK_BYTES )
  272.             USAGE "%s: too small", a);
  273.         if( cardarg > XR_MAX_THREAD_STACK_BYTES )
  274.             USAGE "%s: too big", a);
  275.         XR_threadStackBytes = XR_ComputeAddress( cardarg, 0, XR_ROUND_UP );
  276.         continue;
  277.     }
  278.  
  279.     if( AEQ("-std") || AEQ("-stdiop") ) {
  280.         if( i >= argc ) USAGE "%s: missing arg", a);
  281.         cardarg = (unsigned) atoi(argv[i++]);
  282.         ECHO "  %s %d\n", a, cardarg);
  283.         if( cardarg == 0 )
  284.             USAGE "%s: too small", a);
  285.         XR_maxStdIOPs = cardarg;
  286.         continue;
  287.     }
  288.  
  289.     if( AEQ("-str") || AEQ("-striop") ) {
  290.         if( i >= argc ) XR_Usage("%s: missing arg", a);
  291.         cardarg = (unsigned) atoi(argv[i++]);
  292.         ECHO "  %s %d\n", a, cardarg);
  293.         if( cardarg == 0 )
  294.             USAGE "%s: too small", a);
  295.         XR_maxStrIOPs = cardarg;
  296.         continue;
  297.     }
  298.  
  299.     if( AEQ("-thread") ) {
  300.         XR_maxThreads = 0;
  301.         XR_maxThreadStackGroups = 0;
  302.         ECHO "  %s ", a);
  303.         for(;;) {
  304.             if( (i >= argc) || (argv[i][0] == '-') ) {
  305.                 if( XR_maxThreads == 0 ) {
  306.                     USAGE "%s: missing count arg", a);
  307.                 } else {
  308.                     break;
  309.                 }
  310.             }
  311.             cardarg = (unsigned) atoi(argv[i++]);
  312.             ECHO "  %d", cardarg);
  313.             if( cardarg == 0 )
  314.                 USAGE "%s: too small", a);
  315.             if( (i >= argc) || (argv[i][0] == '-') ) {
  316.                 if( XR_maxThreads == 0 ) {
  317.                     XR_maxThreads = cardarg;
  318.                     break;
  319.                 } else {
  320.                     USAGE "-thread: missing stacksize arg");
  321.                 }
  322.             }
  323.             XR_maxThreads += cardarg;
  324.             if( XR_maxThreadStackGroups >= XR_MAX_THREAD_STACK_GROUPS )
  325.                 USAGE "%s: too many thread stack groups", a);
  326.             XR_threadStackGroups[XR_maxThreadStackGroups].tsg_numThreads =
  327.                     cardarg;
  328.             cardarg = (unsigned) atoi(argv[i++]);
  329.             ECHO "  %d", cardarg);
  330.             if( cardarg < XR_MIN_THREAD_STACK_BYTES )
  331.                 USAGE "%s: stacksize too small", a);
  332.             cardarg = XR_RoundToPage(cardarg, XR_ROUND_UP);
  333.             if( cardarg > XR_MAX_THREAD_STACK_BYTES )
  334.                 USAGE "%s: stacksize too big", a);
  335.             if( (XR_maxThreadStackGroups > 0) && (cardarg <
  336.                     XR_threadStackGroups[XR_maxThreadStackGroups-1] .
  337.                     tsg_stackBytes) ) {
  338.                 USAGE "%s: stack sizes not increasing", a);
  339.             }
  340.             XR_threadStackGroups[XR_maxThreadStackGroups].tsg_stackBytes =
  341.                         cardarg;
  342.                 XR_maxThreadStackGroups += 1;
  343.         }
  344.         if( XR_maxThreads > XR_MAX_THREADS )
  345.             USAGE "%s: too many threads", a);
  346.         continue;
  347.     }
  348.  
  349.     if( AEQ("-tmp") || AEQ("-tmpdir") ) {
  350.         if( i >= argc ) USAGE "%s: missing arg", a);
  351.         strarg = argv[i++];
  352.         ECHO "  %s %s\n", a, strarg);
  353.         if( XR_SetTmpDirectory(strarg) != 0 )
  354.             USAGE "%s: illegal directory name", a);
  355.         continue;
  356.     }
  357.  
  358.     if( AEQ("-vp") ) {
  359.         if( i >= argc ) USAGE "%s: missing arg", a);
  360.         cardarg = (unsigned) atoi(argv[i++]);
  361.         ECHO "  %s %d\n", a, cardarg);
  362.         if( cardarg == 0 )
  363.             USAGE "%s: too small", a);
  364.         if( cardarg > XR_MAX_VPS )
  365.             USAGE "%s: too big", a);
  366.         XR_maxVPs = cardarg;
  367.         continue;
  368.     }
  369.     if( AEQ("--") ) {
  370.         break;
  371.     }
  372.     if( AEQ("-") ) {
  373.         USAGE "", 0);
  374.     }
  375.     if( a[0] == '-' ) {
  376.         ECHO "%s: ", a);
  377.         USAGE "bad arg: %s", a );
  378.     }
  379.     }
  380. }
  381. #undef ECHO
  382.  
  383.  
  384.  
  385. static void
  386. XR_ArgsMsg(fmt, x1, x2, x3, x4)
  387.     char *fmt;
  388.     XR_Pointer x1, x2, x3, x4;
  389. {
  390.     XR_LogVMsg fmt, x1, x2, x3, x4);
  391. }
  392.  
  393. static void
  394. XR_Usage (fmt, x)
  395.     char *fmt;
  396.     unsigned x;
  397. {
  398. #   define PUT XR_FPrintF(XR_MSG_STDOUT,
  399.  
  400.     if( ! XR_VERBOSE(XR_VERBOSITY_ERROR) ) return;
  401.     PUT "\n");
  402.     PUT "%s: ", XR_argv[0]);
  403.     PUT fmt, x);
  404.     PUT "\nUsage: %s ", XR_argv[0]);
  405.     PUT "\t[-quiet [number]] [-verbose [number]]\n");
  406.     PUT "[-vp number] [-slaveiop number] [-stdiop number] [-striop number]\n");
  407.     PUT "\t[-thread number stk ...] [-mem bytes] [-stack bytes]\n");
  408.     PUT "\t[-shmtype type [arg]]\n");
  409.     PUT "\t[-dyload [filename]] [-nodyload]\n");
  410.     PUT "\t[-dbxscript [filename]] [-nodbxscript]\n");
  411.     PUT "\t[-tmpdir [filename]]\n");
  412.     PUT "\t-- (args for after startup)\n");
  413.     _exit(-1);
  414. }
  415. #undef PUT
  416.  
  417.  
  418. static void
  419. XR_PkgMsg(fmt, x1, x2, x3, x4)
  420.     char *fmt;
  421.     XR_Pointer x1, x2, x3, x4;
  422. {
  423.     XR_VerboseVMsg fmt, x1, x2, x3, x4);
  424. }
  425.  
  426. static void
  427. XR_PkgUsage(fmt, x)
  428.     char *fmt;
  429.     unsigned x;
  430. {
  431.     XR_ErrorVMsg "\n%s: fatal error in setup: ", XR_argv[0]);
  432.     XR_ErrorVMsg fmt, x);
  433.     XR_ErrorVMsg "\n");
  434.     _exit(-1);
  435. }
  436.  
  437. static void
  438. XR_IncludeTheseProcsInPCR()
  439. {
  440.     strcasecmp();
  441.     strncasecmp();
  442. }
  443.  
  444.  
  445.  
  446. static int
  447. XR_FindExecutableFileUsingSearchRules(buf, bufLen, shortName)
  448.     char *buf;
  449.     int bufLen;
  450.     char *shortName;
  451. {
  452.     char *pathEnv;
  453.     char *p, *q, *cwd;
  454.     int pathLen, shortNameLen, cwdLen;
  455.  
  456.     cwd = (char *)(getenv("PWD"));
  457.     cwdLen = ((cwd) ? strlen(cwd) : 0);
  458.  
  459.     if( shortName[0] == '/' ) {
  460.         pathEnv = "/";
  461.     } else if( strchr(shortName, '/') != NIL ) {
  462.         if( cwdLen == 0 ) return (-1);
  463.         pathEnv = cwd;
  464.     } else {
  465.         if( (pathEnv = (char *)(getenv("PATH"))) == NIL ) return (-1);
  466.     }
  467.     shortNameLen = strlen(shortName);
  468.     q = pathEnv;
  469.     for(;;) {
  470.         p = q;
  471.         while( *p == ':' ) p++;
  472.         if( *p == 0 ) return (-1);
  473.         q = p;
  474.         while( (*q != ':') && (*q != 0) ) q++;
  475.         pathLen = (q - p);
  476.         if( p[0] == '/' ) {
  477.             if( pathLen >= bufLen ) continue;
  478.             (void)bcopy(p, buf, pathLen);
  479.         } else {
  480.             if( cwdLen == 0 ) continue;
  481.             if( p[0] == '.' ) { p++; pathLen--; }
  482.             if( (cwdLen + 1 + pathLen) >= bufLen ) continue;
  483.             (void)bcopy(cwd, buf, cwdLen);
  484.             buf[cwdLen] = '/';
  485.             if( pathLen > 0 ) (void)bcopy(p, &(buf[cwdLen+1]), pathLen);
  486.             pathLen += (cwdLen+1);
  487.         }
  488.         if( (pathLen + 1 + shortNameLen) >= bufLen ) continue;
  489.         buf[pathLen] = '/';
  490.         strcpy(buf+pathLen+1, shortName);
  491.         if( access(buf, X_OK) == 0 ) return 0;
  492.     }
  493.     /*NOTREACHED*/
  494. }
  495.  
  496.  
  497.  
  498. extern void XR_InitAndRun();
  499.  
  500. void
  501. main(argc, argv)
  502.     int argc;
  503.     char ** argv;
  504. {
  505.     int pkgArgC;
  506.     char **pkgArgV;
  507.     int ans;
  508.     char fnBuf[1024];
  509.  
  510.     XR_argc = argc;
  511.     XR_argv = argv;
  512.  
  513.     if( argc < 1 ) XR_Panic("main argc == 0");
  514.  
  515.     ans = XR_FindExecutableFileUsingSearchRules(
  516.             fnBuf, (sizeof fnBuf), argv[0] );
  517.     if( ans == 0 ) ans = XR_SetPCRFileName(fnBuf);
  518.     if( ans != 0 ) XR_Usage("bad PCR name", NIL);
  519.  
  520.     XR_GetPackageDefaultArgs(&pkgArgC, &pkgArgV);
  521.     if( pkgArgC > 0 ) {
  522.         XR_PrintHelloWorld(XR_VERBOSITY_VERBOSE);
  523.         XR_ParseSwitches(pkgArgC, pkgArgV, XR_PkgMsg, XR_PkgUsage);
  524.     }
  525.     if( argc > 1 ) {
  526.         XR_PrintHelloWorld(XR_VERBOSITY_LOG);
  527.         XR_ParseSwitches(argc-1, argv+1, XR_ArgsMsg, XR_Usage);
  528.     }
  529.  
  530.     XR_PrintHelloWorld(XR_VERBOSITY_NORMAL);
  531.     XR_Configure();
  532.  
  533.     XR_InitAndRun();
  534.     /* no return */
  535.  
  536.     _exit(0);
  537. }
  538.  
  539.  
  540.